package com.plug.utils.netty;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyServer implements Runnable {
	public static Logger log = LoggerFactory.getLogger(NettyServer.class);
	
	private NettyConfig nettyConfig;
	private static NettyServer nettyServer;
	
	private NettyServer(NettyConfig nettyConfig) {
		super();
		this.nettyConfig = nettyConfig;
	}
	public static NettyServer init(NettyConfig nettyConfig) {
		if (nettyServer==null) {
			nettyServer=new NettyServer(nettyConfig);
		}
		return nettyServer;
	}
	public void run() {		
		log.info("---------- netty服务端开启等待连接 ----------");
		//NioEventLoopGroup是一个多线程的I/O操作事件循环池，Netty为各种传输方式提供了多种EventLoopGroup的实现。NioEventLoopGroup专门用于网络事件的处理，实际上它们就是Reactor线程组
		EventLoopGroup bossGroup = new NioEventLoopGroup();//用于服务端接受客服端的链接
		EventLoopGroup workerGroup = new NioEventLoopGroup();//用于进行SocketChannel的网络读写

		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup);
			b.channel(NioServerSocketChannel.class);//选择tcp类型的channel
			nettyConfig.setChannelOption(b);//设置Channel参数
			b.childHandler(nettyConfig.getChannelHandler());//绑定了I/O事件的处理类，它的作用类似于Reactor当中的handler，主要用于处理网络是I/O事件，例如记录日志、对消息进行编解码等。

			// 绑定端口
			b.bind(nettyConfig.getPort())
			.sync()
			// 等待服务端监听端口关闭
			.channel()
			.closeFuture()
			.sync();
			
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}

	}
}
